package org.mijia.dotsbox.rcp;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Listener;


/**
 * Reference: RSSOwl Project
 * Please check out the license of RSSOwl (http://www.rssowl.org)
 */
 
 
/**
 * Instances of this class implement a Composite that lays out three children
 * horizontally and allows programmatic control of layout and border parameters.
 * ViewForm is used in the workbench to implement a view's label/menu/toolbar
 * local bar.
 * <p>
 * Note that although this class is a subclass of <code>Composite</code>, it
 * does not make sense to set a layout on it.
 * </p>
 * <p>
 * <dl>
 * <dt><b>Styles: </b></dt>
 * <dd>BORDER, FLAT</dd>
 * <dt><b>Events: </b></dt>
 * <dd>(None)</dd>
 * </dl>
 * <p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </p>
 */

public class ViewForm extends Composite {
	private static final int OFFSCREEN = -200;

	/**
	 * marginHeight specifies the number of pixels of vertical margin that will
	 * be placed along the top and bottom edges of the form. The default value
	 * is 0.
	 */
	public int marginHeight = 0;

	/**
	 * marginWidth specifies the number of pixels of horizontal margin that will
	 * be placed along the left and right edges of the form. The default value
	 * is 0.
	 */
	public int marginWidth = 0;
	private int BORDER_BOTTOM = 0;
	private int BORDER_LEFT = 0;
	private int BORDER_RIGHT = 0;
	private int BORDER_TOP = 0;
	private Control content;
	private boolean draw3DBorder;
	private int drawLine1 = -1;
	private int drawLine2 = -1;
	private boolean isToolBarMode = false;
	private Rectangle oldArea;
	private boolean onlyBorderBottom;
	private boolean onlyBorderTop;
	private boolean onlyBorderTopBottom;
	private boolean separateTopCenter = false;
	private boolean showBorder = false;
	private Control topCenter;

	/** SWT widgets */
	private Control topLeft;
	private Control topRight;

	public Color grayViewFormColor;
	public Color viewFormBorderInsideColor;
	public Color viewFormBorderMiddleColor;
	public Color viewFormBorderOutsideColor;

	/**
	 * Constructs a new instance of this class given its parent and a style
	 * value describing its behavior and appearance.
	 * <p>
	 * The style value is either one of the style constants defined in class
	 * <code>SWT</code> which is applicable to instances of this class, or
	 * must be built by <em>bitwise OR</em> 'ing together (that is, using the
	 * <code>int</code> "|" operator) two or more of those <code>SWT</code>
	 * style constants. The class description lists the style constants that are
	 * applicable to the class. Style bits are also inherited from superclasses.
	 * </p>
	 * 
	 * @param parent
	 *            a widget which will be the parent of the new instance (cannot
	 *            be null)
	 * @param style
	 *            the style of widget to construct
	 * @exception IllegalArgumentException
	 *                <ul>
	 *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
	 *                </ul>
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the parent</li>
	 *                </ul>
	 * @see SWT#BORDER
	 * @see SWT#FLAT
	 * @see #getStyle()
	 */
	public ViewForm(Composite parent, int style) {
		super(parent, checkStyle(style));

		grayViewFormColor = new Color(getDisplay(), 241, 240, 234);
		viewFormBorderInsideColor = new Color(getDisplay(), 162, 160, 162);
		viewFormBorderMiddleColor = new Color(getDisplay(), 173, 171, 168);
		viewFormBorderOutsideColor = new Color(getDisplay(), 201, 198, 195);

		draw3DBorder = ((style & SWT.FLAT) == 0);
		setBorderVisible((style & SWT.BORDER) != 0);

		addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent event) {
				onPaint(event.gc);
			}
		});
		addControlListener(new ControlAdapter() {
			public void controlResized(ControlEvent e) {
				onResize();
			}
		});

		addListener(SWT.Dispose, new Listener() {
			public void handleEvent(Event e) {
				onDispose();
			}
		});
	}

	static int checkStyle(int style) {
		int mask = SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
		return style & mask | SWT.NO_REDRAW_RESIZE;
	}

	public Point computeSize(int wHint, int hHint, boolean changed) {
		checkWidget();
		// size of title bar area
		Point leftSize = new Point(0, 0);
		if (topLeft != null) {
			leftSize = topLeft.computeSize(SWT.DEFAULT, SWT.DEFAULT);
			leftSize.x += (isToolBarMode ? 0 : 1); // +1 for highlight line
		}
		Point centerSize = new Point(0, 0);
		if (topCenter != null) {
			centerSize = topCenter.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		}
		Point rightSize = new Point(0, 0);
		if (topRight != null) {
			rightSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		}
		Point size = new Point(0, 0);
		// calculate width of title bar
		if (separateTopCenter
				|| (wHint != SWT.DEFAULT && leftSize.x + centerSize.x
						+ rightSize.x > wHint)) {
			size.x = leftSize.x + rightSize.x;
			size.x = Math.max(centerSize.x, size.x);
			size.y = Math.max(leftSize.y, rightSize.y)
					+ (isToolBarMode ? 0 : 1); // +1 for highlight line
			if (topCenter != null) {
				size.y += centerSize.y;
			}
		} else {
			size.x = leftSize.x + centerSize.x + rightSize.x;
			size.y = Math.max(leftSize.y, Math.max(centerSize.y, rightSize.y))
					+ (isToolBarMode ? 0 : 1); // +1 for highlight line
		}

		if (content != null) {
			Point contentSize = new Point(0, 0);
			contentSize = content.computeSize(SWT.DEFAULT, SWT.DEFAULT);
			size.x = Math.max(size.x, contentSize.x);
			size.y += contentSize.y + 1; // +1 for line bewteen content and
											// header
		}

		size.x += 2 * marginWidth;
		size.y += 2 * marginHeight;

		if (wHint != SWT.DEFAULT)
			size.x = wHint;
		if (hHint != SWT.DEFAULT)
			size.y = hHint;

		Rectangle trim = computeTrim(0, 0, size.x, size.y);
		return new Point(trim.width, trim.height);
	}

	public Rectangle computeTrim(int x, int y, int width, int height) {
		checkWidget();
		int trimX = x - BORDER_LEFT;
		int trimY = y - BORDER_TOP;
		int trimWidth = width + BORDER_LEFT + BORDER_RIGHT;
		int trimHeight = height + BORDER_TOP + BORDER_BOTTOM;
		return new Rectangle(trimX, trimY, trimWidth, trimHeight);
	}

	public Rectangle getClientArea() {
		checkWidget();
		Rectangle clientArea = super.getClientArea();
		clientArea.x += BORDER_LEFT;
		clientArea.y += BORDER_TOP;
		clientArea.width -= BORDER_LEFT + BORDER_RIGHT;
		clientArea.height -= BORDER_TOP + BORDER_BOTTOM;
		return clientArea;
	}

	/**
	 * Returns the content area.
	 * 
	 * @return the control in the content area of the pane or null
	 */
	public Control getContent() {
		return content;
	}

	/**
	 * Returns Control that appears in the top center of the pane. Typically
	 * this is a toolbar.
	 * 
	 * @return the control in the top center of the pane or null
	 */
	public Control getTopCenter() {
		return topCenter;
	}

	/**
	 * Returns the Control that appears in the top left corner of the pane.
	 * Typically this is a label such as CLabel.
	 * 
	 * @return the control in the top left corner of the pane or null
	 */
	public Control getTopLeft() {
		return topLeft;
	}

	/**
	 * Returns the control in the top right corner of the pane. Typically this
	 * is a Close button or a composite with a Menu and Close button.
	 * 
	 * @return the control in the top right corner of the pane or null
	 */
	public Control getTopRight() {
		return topRight;
	}

	public void layout(boolean changed) {
		checkWidget();
		Rectangle rect = getClientArea();

		drawLine1 = -1;
		drawLine2 = -1;

		Point leftSize = new Point(0, 0);
		if (topLeft != null && !topLeft.isDisposed()) {
			leftSize = topLeft.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		}
		Point centerSize = new Point(0, 0);
		if (topCenter != null && !topCenter.isDisposed()) {
			centerSize = topCenter.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		}
		Point rightSize = new Point(0, 0);
		if (topRight != null && !topRight.isDisposed()) {
			rightSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		}

		int minTopWidth = leftSize.x + centerSize.x + rightSize.x + 2
				* marginWidth + (isToolBarMode ? 0 : 1); // +1 for highlight
															// line
		int height = rect.y + marginHeight;

		boolean top = false;
		if (separateTopCenter || minTopWidth > rect.width) {
			int topHeight = Math.max(rightSize.y, leftSize.y);
			if (topRight != null && !topRight.isDisposed()) {
				top = true;
				topRight.setBounds(rect.x + rect.width - marginWidth
						- rightSize.x, rect.y + 1 + marginHeight, rightSize.x,
						topHeight);
				height += 1 + topHeight; // +1 for highlight line
			}
			if (topLeft != null && !topLeft.isDisposed()) {
				top = true;
				leftSize = topLeft.computeSize(rect.width - 2 * marginWidth
						- rightSize.x - 1, SWT.DEFAULT);
				topLeft.setBounds(rect.x + (isToolBarMode ? 0 : 1)
						+ marginWidth, rect.y + (isToolBarMode ? 0 : 1)
						+ marginHeight, leftSize.x, topHeight);
				height = Math.max(height, rect.y + marginHeight
						+ (isToolBarMode ? 0 : 1) + topHeight); // +1 for
																// highlight
																// line
			}
			if (topCenter != null && !topCenter.isDisposed()) {
				top = true;
				if (height > rect.y + marginHeight) {
					drawLine1 = height;
					height += 1; // +1 for divider line
				}
				centerSize = topCenter.computeSize(
						rect.width - 2 * marginWidth, SWT.DEFAULT);

				/** In ToolBar Mode draw Line under Center Control */
				if (isToolBarMode && content == null) {
					drawLine1 = -1;
					height -= 1;
				}

				topCenter.setBounds(rect.x + rect.width - marginWidth
						- centerSize.x, height, centerSize.x, centerSize.y);
				height += centerSize.y;
			}
		} else {
			int topHeight = Math.max(rightSize.y, Math.max(centerSize.y,
					leftSize.y));
			if (topRight != null && !topRight.isDisposed()) {
				top = true;
				topRight.setBounds(rect.x + rect.width - marginWidth
						- rightSize.x, rect.y + marginHeight + 1, // +1 for
																	// highlight
																	// line
						rightSize.x, topHeight);
				height += 1 + topHeight; // +1 for highlight line
			}
			if (topCenter != null && !topCenter.isDisposed()) {
				top = true;

				/** In ToolBar Mode let Center Control fill */
				if (isToolBarMode)
					topCenter.setBounds(rect.x + leftSize.x - marginWidth,
							rect.y + marginHeight, rect.width - 2 * marginWidth
									- leftSize.x, topHeight);
				else
					topCenter.setBounds(rect.x + rect.width - marginWidth
							- rightSize.x - centerSize.x, rect.y + marginHeight
							+ 1, centerSize.x, topHeight);

				height = Math.max(height, rect.y + marginHeight
						+ (isToolBarMode ? 0 : 1) + topHeight); // +1 for
																// highlight
																// line
			}
			if (topLeft != null && !topLeft.isDisposed()) {
				top = true;
				leftSize = isToolBarMode ? leftSize = topLeft.computeSize(
						SWT.DEFAULT, topHeight) : topLeft.computeSize(
						rect.width - 2 * marginWidth - rightSize.x
								- centerSize.x - 1, topHeight);
				topLeft.setBounds(rect.x + marginWidth
						+ (isToolBarMode ? 0 : 1), // +1 for highlight line
						rect.y + marginHeight + (isToolBarMode ? 0 : 1), // +1
																			// for
																			// highlight
																			// line
						leftSize.x, topHeight);
				height = Math.max(height, rect.y + marginHeight
						+ (isToolBarMode ? 0 : 1) + topHeight); // +1 for
																// highlight
																// line
			}
		}

		if (content != null && !content.isDisposed()) {
			if (top) {
				drawLine2 = height;
				height += 1; // +1 for divider line
			}
			content
					.setBounds(rect.x + marginWidth, height, rect.width - 2
							* marginWidth, rect.y + rect.height - height
							- marginHeight);
		}
	}

	/**
	 * Show / Hide the 3D Border of the ViewForm
	 * 
	 * @param show
	 *            If TRUE, show the 3D Boreder
	 */
	public void set3DBorderState(boolean show) {

		/** If state did not change, return */
		if (show == draw3DBorder)
			return;

		/** Else, apply new state and redraw */
		draw3DBorder = show;
		redraw();
	}

	/**
	 * Specify whether the border should be displayed or not.
	 * 
	 * @param show
	 *            true if the border should be displayed
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setBorderVisible(boolean show) {
		checkWidget();
		if (showBorder == show)
			return;

		showBorder = show;
		if (showBorder) {
			if ((getStyle() & SWT.FLAT) != 0 || !draw3DBorder) {
				BORDER_LEFT = BORDER_TOP = BORDER_RIGHT = BORDER_BOTTOM = 1;
			} else {
				BORDER_LEFT = BORDER_TOP = 1;
				BORDER_RIGHT = BORDER_BOTTOM = 3;
			}
		} else {
			BORDER_BOTTOM = BORDER_TOP = BORDER_LEFT = BORDER_RIGHT = 0;
		}

		layout();
		redraw();
	}

	/**
	 * Sets the content. Setting the content to null will remove it from the
	 * pane - however, the creator of the content must dispose of the content.
	 * 
	 * @param content
	 *            the control to be displayed in the content area or null
	 * @param layout
	 *            If TRUE, layout the ViewForm
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                <li>ERROR_INVALID_ARGUMENT - if the control is not a
	 *                child of this ViewForm</li>
	 *                </ul>
	 */
	public void setContent(Control content, boolean layout) {
		checkWidget();
		if (content != null && content.getParent() != this) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		if (this.content != null && !this.content.isDisposed()) {
			this.content.setBounds(OFFSCREEN, OFFSCREEN, 0, 0);
		}
		this.content = content;

		if (layout)
			layout();
	}

	public void setFont(Font f) {
		super.setFont(f);
		if (topLeft != null && !topLeft.isDisposed())
			topLeft.setFont(f);
		if (topCenter != null && !topCenter.isDisposed())
			topCenter.setFont(f);
		if (topRight != null && !topRight.isDisposed())
			topRight.setFont(f);

		layout();
	}

	/**
	 * Sets the layout which is associated with the receiver to be the argument
	 * which may be null.
	 * <p>
	 * Note : ViewForm does not use a layout class to size and position its
	 * children.
	 * </p>
	 * 
	 * @param layout
	 *            the receiver's new layout or null
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setLayout(Layout layout) {
		checkWidget();
		return;
	}

	/**
	 * Set that the ViewForm should only paint a single border on bottom. This
	 * hint does only work when SWT.FLAT is also passed to the ViewForm.
	 * 
	 * @param onlyBorderBottom
	 *            If TRUE only paint a single, bottom border
	 */
	public void setOnlyBorderBottom(boolean onlyBorderBottom) {
		this.onlyBorderBottom = onlyBorderBottom;
	}

	/**
	 * Set that the ViewForm should only paint a single border on top. This hint
	 * does only work when SWT.FLAT is also passed to the ViewForm.
	 * 
	 * @param onlyBorderTop
	 *            If TRUE only paint a single, top border
	 */
	public void setOnlyBorderTop(boolean onlyBorderTop) {
		this.onlyBorderTop = onlyBorderTop;
	}

	/**
	 * Set that the ViewForm should only paint a single border on top and
	 * bottom. This hint does only work when SWT.FLAT is also passed to the
	 * ViewForm.
	 * 
	 * @param onlyBorderTopBottom
	 *            If TRUE only paint a single, bottom border
	 */
	public void setOnlyBorderTopBottom(boolean onlyBorderTopBottom) {
		this.onlyBorderTopBottom = onlyBorderTopBottom;
	}

	/**
	 * @param isToolBarMode
	 *            If TRUE, switch ViewForm into ToolBar Mode. In ToolBar Mode
	 *            the visual presentation of the Center Control is different
	 *            from the normal Mode.
	 */
	public void setToolBarMode(boolean isToolBarMode) {
		this.isToolBarMode = isToolBarMode;
	}

	/**
	 * Set the control that appears in the top center of the pane. Typically
	 * this is a toolbar. The topCenter is optional. Setting the topCenter to
	 * null will remove it from the pane - however, the creator of the topCenter
	 * must dispose of the topCenter.
	 * 
	 * @param topCenter
	 *            the control to be displayed in the top center or null
	 * @param layout
	 *            If TRUE, layout the ViewForm
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                <li>ERROR_INVALID_ARGUMENT - if the control is not a
	 *                child of this ViewForm</li>
	 *                </ul>
	 */
	public void setTopCenter(Control topCenter, boolean layout) {
		checkWidget();
		if (topCenter != null && topCenter.getParent() != this) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		if (this.topCenter != null && !this.topCenter.isDisposed()) {
			this.topCenter.setBounds(OFFSCREEN, OFFSCREEN, 0, 0);
		}
		this.topCenter = topCenter;

		if (layout)
			layout();
	}

	/**
	 * If true, the topCenter will always appear on a separate line by itself,
	 * otherwise the topCenter will appear in the top row if there is room and
	 * will be moved to the second row if required.
	 * 
	 * @param show
	 *            true if the topCenter will always appear on a separate line by
	 *            itself
	 * @param layout
	 *            If TRUE, layout the ViewForm
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setTopCenterSeparate(boolean show, boolean layout) {
		checkWidget();
		separateTopCenter = show;

		if (layout)
			layout();
	}

	/**
	 * Set the control that appears in the top left corner of the pane.
	 * Typically this is a label such as CLabel. The topLeft is optional.
	 * Setting the top left control to null will remove it from the pane -
	 * however, the creator of the control must dispose of the control.
	 * 
	 * @param c
	 *            the control to be displayed in the top left corner or null
	 * @param layout
	 *            If TRUE, layout the ViewForm
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                <li>ERROR_INVALID_ARGUMENT - if the control is not a
	 *                child of this ViewForm</li>
	 *                </ul>
	 */
	public void setTopLeft(Control c, boolean layout) {
		checkWidget();
		if (c != null && c.getParent() != this) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		if (this.topLeft != null && !this.topLeft.isDisposed()) {
			this.topLeft.setBounds(OFFSCREEN, OFFSCREEN, 0, 0);
		}
		this.topLeft = c;

		if (layout)
			layout();
	}

	/**
	 * Set the control that appears in the top right corner of the pane.
	 * Typically this is a Close button or a composite with a Menu and Close
	 * button. The topRight is optional. Setting the top right control to null
	 * will remove it from the pane - however, the creator of the control must
	 * dispose of the control.
	 * 
	 * @param c
	 *            the control to be displayed in the top right corner or null
	 * @param layout
	 *            If TRUE, layout the ViewForm
	 * @exception SWTException
	 *                <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                <li>ERROR_INVALID_ARGUMENT - if the control is not a
	 *                child of this ViewForm</li>
	 *                </ul>
	 */
	public void setTopRight(Control c, boolean layout) {
		checkWidget();
		if (c != null && c.getParent() != this) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		if (this.topRight != null && !this.topRight.isDisposed()) {
			this.topRight.setBounds(OFFSCREEN, OFFSCREEN, 0, 0);
		}
		this.topRight = c;

		if (layout)
			layout();
	}

	void onDispose() {
		topLeft = null;
		topCenter = null;
		topRight = null;
		content = null;
		oldArea = null;

		grayViewFormColor.dispose();
		viewFormBorderInsideColor.dispose();
		viewFormBorderMiddleColor.dispose();
		viewFormBorderOutsideColor.dispose();
	}

	void onPaint(GC gc) {
		Rectangle d = super.getClientArea();

		if (showBorder) {
			if ((getStyle() & SWT.FLAT) != 0 || !draw3DBorder) {
				gc.setForeground(viewFormBorderInsideColor);
				if (onlyBorderTopBottom) {
					gc.drawLine(d.x, d.y + d.height - 1, d.x + d.width - 1, d.y
							+ d.height - 1);
					gc.drawLine(d.x, d.y, d.x + d.width - 1, d.y);
				} else if (onlyBorderTop)
					gc.drawLine(d.x, d.y, d.x + d.width - 1, d.y);
				else if (onlyBorderBottom)
					gc.drawLine(d.x, d.y + d.height - 1, d.x + d.width - 1, d.y
							+ d.height - 1);
				else
					gc.drawRectangle(d.x, d.y, d.x + d.width - 1, d.y
							+ d.height - 1);
			} else {
				gc.setForeground(viewFormBorderInsideColor);
				gc.drawRectangle(d.x, d.y, d.x + d.width - 3, d.y + d.height
						- 3);

				gc.setForeground(viewFormBorderMiddleColor);
				gc.drawLine(d.x + 1, d.y + d.height - 2, d.x + d.width - 1, d.y
						+ d.height - 2);
				gc.drawLine(d.x + d.width - 2, d.y + 1, d.x + d.width - 2, d.y
						+ d.height - 1);

				gc.setForeground(viewFormBorderOutsideColor);
				gc.drawLine(d.x + 2, d.y + d.height - 1, d.x + d.width - 2, d.y
						+ d.height - 1);
				gc.drawLine(d.x + d.width - 1, d.y + 2, d.x + d.width - 1, d.y
						+ d.height - 2);
			}
		}

		if (drawLine1 != -1) {
			// top seperator line
			gc.setForeground(viewFormBorderInsideColor);
			gc.drawLine(d.x + BORDER_LEFT - 1, drawLine1, d.x + d.width
					- BORDER_RIGHT, drawLine1);
		}
		if (drawLine2 != -1) {
			// content separator line
			int freeSpaceOnLeft = (onlyBorderBottom || onlyBorderTop || onlyBorderTopBottom) ? 1
					: 0;
			gc.setForeground(viewFormBorderInsideColor);
			gc.drawLine(d.x + BORDER_LEFT - freeSpaceOnLeft, drawLine2, d.x
					+ d.width - BORDER_RIGHT, drawLine2);
		}
		// highlight on top
		int y = drawLine1;
		if (y == -1) {
			y = drawLine2;
		}
		if (y != -1) {
			gc.setForeground(getDisplay().getSystemColor(
					SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
			gc.drawLine(d.x + BORDER_LEFT + marginWidth, d.y + BORDER_TOP
					+ marginHeight, d.x + BORDER_LEFT + marginWidth, y - 1);
			gc.drawLine(d.x + BORDER_LEFT + marginWidth, d.y + BORDER_TOP
					+ marginHeight, d.x + d.width - BORDER_RIGHT - marginWidth
					- 1, d.y + BORDER_TOP + marginHeight);
		}

		gc.setForeground(getForeground());
	}

	void onResize() {
		layout();

		Rectangle area = super.getClientArea();
		if (oldArea == null || oldArea.width == 0 || oldArea.height == 0) {
			redraw();
		} else {
			int width = 0;
			if (oldArea.width < area.width) {
				width = area.width - oldArea.width + BORDER_RIGHT;
			} else if (oldArea.width > area.width) {
				width = BORDER_RIGHT;
			}
			redraw(area.x + area.width - width, area.y, width, area.height,
					false);

			int height = 0;
			if (oldArea.height < area.height) {
				height = area.height - oldArea.height + BORDER_BOTTOM;
			}
			if (oldArea.height > area.height) {
				height = BORDER_BOTTOM;
			}
			redraw(area.x, area.y + area.height - height, area.width, height,
					false);
		}
		oldArea = area;
	}
}